package random;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class WalkRenderer extends JPanel{
	
	private double[][] pointsTail ={{0,0},{0,0}};
	private double[][] pointsHead = new double[0][0];
	private int size, scale;
	private double minX,minY,maxX,maxY;
	private JFrame frame;
	private int gridSize = 0;
	
	public WalkRenderer(int size, int scale) {
		super(new BorderLayout(),true);
		this.setBackground(Color.BLACK);
		this.size = size;
		this.scale = scale;
		frame = new JFrame("SAW");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setPreferredSize(new Dimension(size, size));
		this.setVisible(true);
		frame.getContentPane().add(this,BorderLayout.CENTER);
		frame.setUndecorated(false);
		//frame.setSize(size*scale, size*scale);
		frame.pack();
//		points[0][0] =size/2;
//		points[0][1] =size/2;
		frame.setVisible(true);
	}
	
	public WalkRenderer(int size, int scale, int gridSize) {
		this(size,scale);
		this.gridSize = gridSize;
	}
	
	/**
	 * Set the points that will be the Tail (here the white SAW)
	 * @param walk
	 */
	public void setWalkTail(double[][] walk){
		pointsTail = walk;
		this.trimSize();
		this.repaint();
	}
	
	/**
	 * Set the points that will be the Head (here the blue SAW)
	 * @param walk
	 */
	public void setWalkHead(double[][] walk){
		pointsHead = walk;
		this.trimSize();
		this.repaint();
	}
	
	private void trimSize(){
		minX=Double.MAX_VALUE; 
		minY=Double.MAX_VALUE; 
		maxX=0; 
		maxY=0;
		for (double[] ds : pointsTail) {
			minX = Math.min(ds[0], minX);
			minY = Math.min(ds[1], minY);
			maxX = Math.max(ds[0], maxX);
			maxY = Math.max(ds[1], maxY);
		}
		for (double[] ds : pointsHead) {
			minX = Math.min(ds[0], minX);
			minY = Math.min(ds[1], minY);
			maxX = Math.max(ds[0], maxX);
			maxY = Math.max(ds[1], maxY);
		}
	}
	
	




	@Override
	public void paint(Graphics gra) {
		super.paint(gra);
		Graphics2D g = (Graphics2D) gra;
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g.setColor(Color.GREEN);
		double localScale = scale;
		int h = this.getHeight()/2;
		int w = this.getWidth()/2;
		g.drawLine(w-2, h-2,w+2, h+2);
		g.drawLine(w-2, h+2,w+2, h-2);
		
		//g.setColor(Color.WHITE);
		double[] o = pointsTail[0];
		if((-minX+o[0])*localScale > w){
			localScale = (w/(-minX+o[0]));
		}
		if((maxX-o[0])*localScale > w){
			localScale = (w/(maxX-o[0]));
		}
		if((-minY+o[1])*localScale > h){
			localScale = (h/(-minY+o[1]));
		}
		if((maxY-o[1])*localScale > h){
			localScale = (h/(maxY-o[1]));
		} 
		localScale*=0.99;
		
		if(gridSize > 0){
			g.setColor(Color.DARK_GRAY);
			for (int i = -(int)(w/(gridSize*localScale)); i <= (int)(w/(gridSize*localScale)); i++) {
				g.drawLine((int)((i*gridSize)*localScale)+w, 0
						, (int)((i*gridSize)*localScale)+w, 2 * h);
			}
			for (int i = -(int)(h/(gridSize*localScale)); i <= (int)(h/(gridSize*localScale)); i++) {
				g.drawLine(0,(int)((i*gridSize)*localScale)+h
						, 2 * w , (int)((i*gridSize)*localScale)+h);
			}
		}
		
		for (int i = 1; i < pointsTail.length; i++) {
			g.setColor(Color.WHITE);
			g.drawLine((int)((pointsTail[i-1][0]-o[0])*localScale)+w, (int)((-pointsTail[i-1][1]+o[1])*localScale)+h
					, (int)((pointsTail[i][0]-o[0])*localScale)+w, (int)((-pointsTail[i][1]+o[1])*localScale)+h );
			g.setColor(Color.BLACK);
			g.drawLine((int)((pointsTail[i-1][0]-o[0])*localScale)+w, (int)((-pointsTail[i-1][1]+o[1])*localScale)+h
					, (int)((pointsTail[i-1][0]-o[0])*localScale)+w, (int)((-pointsTail[i-1][1]+o[1])*localScale)+h );
		}
		g.setColor(Color.YELLOW);
		int hEnd =  (int)((-pointsTail[pointsTail.length-2][1]+o[1])*localScale)+h;
		int wEnd = (int)((pointsTail[pointsTail.length-2][0]-o[0])*localScale)+w;
		g.drawLine(wEnd-2, hEnd-2,wEnd+2, hEnd+2);
		g.drawLine(wEnd-2, hEnd+2,wEnd+2, hEnd-2);
		g.setColor(Color.RED);
		hEnd =  (int)((-pointsTail[pointsTail.length-1][1]+o[1])*localScale)+h;
		wEnd = (int)((pointsTail[pointsTail.length-1][0]-o[0])*localScale)+w;
		g.drawLine(wEnd-2, hEnd-2,wEnd+2, hEnd+2);
		g.drawLine(wEnd-2, hEnd+2,wEnd+2, hEnd-2);
		if (pointsHead.length>1) {
			for (int i = 1; i < pointsHead.length; i++) {
				g.setColor(Color.BLUE);
				g.drawLine((int) ((pointsHead[i - 1][0] - o[0]) * localScale) + w, (int) ((-pointsHead[i - 1][1] + o[1]) * localScale) + h,
						(int) ((pointsHead[i][0] - o[0]) * localScale) + w, (int) ((-pointsHead[i][1] + o[1]) * localScale) + h);
				g.setColor(Color.BLACK);
				g.drawLine((int) ((pointsHead[i - 1][0] - o[0]) * localScale) + w, (int) ((-pointsHead[i - 1][1] + o[1]) * localScale) + h,
						(int) ((pointsHead[i - 1][0] - o[0]) * localScale) + w, (int) ((-pointsHead[i - 1][1] + o[1]) * localScale) + h);
			}
			g.setColor(Color.YELLOW);
			hEnd = (int) ((-pointsHead[pointsHead.length - 2][1] + o[1]) * localScale) + h;
			wEnd = (int) ((pointsHead[pointsHead.length - 2][0] - o[0]) * localScale) + w;
			g.drawLine(wEnd - 2, hEnd - 2, wEnd + 2, hEnd + 2);
			g.drawLine(wEnd - 2, hEnd + 2, wEnd + 2, hEnd - 2);
			g.setColor(Color.RED);
			hEnd = (int) ((-pointsHead[pointsHead.length - 1][1] + o[1]) * localScale) + h;
			wEnd = (int) ((pointsHead[pointsHead.length - 1][0] - o[0]) * localScale) + w;
			g.drawLine(wEnd - 2, hEnd - 2, wEnd + 2, hEnd + 2);
			g.drawLine(wEnd - 2, hEnd + 2, wEnd + 2, hEnd - 2);
		}
	}
	
}
